# 导入库
import math
import os
import traceback
import pandas as pd
import pywt
import scipy.signal
import numpy as np
import matplotlib.pyplot as plt
import ruptures as rpt
from asammdf import MDF
from statsmodels.tsa.stattools import adfuller
plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决汉字显示为□指定默认字体为黑体。
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像时,负号'-'显示为□和报错的问题。

# 提取INCA的DAT文件数据并分析
def inca(mdf_file_path,s,f):
    try:
        l=[]
        n=0
        # 导入dat文件并提取数据。
        path = os.path.basename(mdf_file_path)# 返回路径最后的文件名。
        print('文件名：',path)
        mdf = MDF(mdf_file_path)# 读取数据。
        chn_db = mdf.channels_db# channels是字典格式。
        if 'Per' in chn_db.keys() :
            df=mdf.get_group(int(str(chn_db['Per'][0]).split("(")[1].split(",")[0]))# # 提取数据，由((5, 19),)可知通道是5，Per是第19个变量。
            df.columns=df.columns.str.split("\\\\").str[0]# df的数据类型是pandas.core.series.Series，内容是Psujtacc\\XCP: 1。
            if (s != '') and f:
                plt.suptitle('{0}'.format(path)+'\n'+'{0} s 到 {1} s '.format(s,f))# 给画布添加标题
                print('起始时间（s）：',s,'和',f)
                l0='分析 {0} 文件从 {1} s 到 {2} s 的数据......'.format(path,s,f)
                l.append(l0)
                # 选择数据范围。
                # 通过行、列的索引位置来截取突加突减部分的数据；不同文件突加突减起始时间和结束时间不同，因此打开不同的文件必须输入不同的时间数据。
                # per=df['Per'].loc[sftime(df['Per'],s,f)[0]:sftime(df['Per'],s,f)[1]]# 转速。
                per=df['Per'].loc[sftime(df['Per'],s,f)[0]:sftime(df['Per'],s,f)[1]]# 转速。
                index_listm = per.index.tolist()# 该代码返回所有的索引号组成的列表。
                pexcurrent=df['Pexcurrent'].loc[index_listm]# 输出负载端电流。
                pet=df['Pet'].loc[index_listm]# 缸温。
                piat=df['Piat'].loc[index_listm]# 进气温度。
                ptd=df['Ptd'].loc[index_listm]# 节气门体开度。
                # 突加突减后的电流转折点图
                plt.subplot(324)
                plt.title("电流图像")
                plt.xlabel("时间/s")
                plt.ylabel("电流/A")
                plt.plot(pexcurrent, zorder=1)
                # 电流的突加突减转折点
                pexcurrent1h=[]# 上升行数
                pexcurrent1=[]# 上升时间
                pexcurrent2h=[]# 下降行数
                pexcurrent2=[]# 下降时间
                pexcurrent1h,pexcurrent2h=Ruptures1(pexcurrent)
                for i in pexcurrent1h:# 0A电流将要上升的行数对应的行数（时间==0）。
                    pexcurrent1.append(index_listm[i])# 0A电流将要上升的行数对应的索引（时间==0）。
                for i in pexcurrent2h:# 电流从高处下降的行数对应的行数（时间!=0）。
                    pexcurrent2.append(index_listm[i])# 电流从高处下降的行数对应的索引（时间!=0）。
                # 去重
                pexcurrent1h=list1(pexcurrent1h)# 行数
                pexcurrent1=list1(pexcurrent1)# 索引
                pexcurrent2h=list1(pexcurrent2h)# 行数
                pexcurrent2=list1(pexcurrent2)# 索引
                plt.plot(pexcurrent.loc[pexcurrent1], '^', zorder=3)
                plt.plot(pexcurrent.loc[pexcurrent2], 'v', zorder=3)
                # 在截取的转速图像上标记最高转速点和最低转速点。
                # 转速的突加突减图像。
                plt.subplot(311)
                plt.title("转速的突加突减图像")
                plt.xlabel("时间/s")
                plt.ylabel("转速/rpm")
                plt.plot(per)
                # 电流修正，加上终止点。
                if pexcurrent.iloc[-1] == 0:
                    pexcurrent1h.append(len(index_listm)-1)# 行数
                    pexcurrent1.append(index_listm[-1])# 索引
                else:
                    pexcurrent2h.append(len(index_listm)-1)# 行数
                    pexcurrent2.append(index_listm[-1])# 索引
                # 去重
                pexcurrent1h=list1(pexcurrent1h)# 行数
                pexcurrent1=list1(pexcurrent1)# 索引
                pexcurrent2h=list1(pexcurrent2h)# 行数
                pexcurrent2=list1(pexcurrent2)# 索引
                # 求转速的波峰和波谷并探索转速突变的边界
                peakspexcurrent=pexcurrent1h+pexcurrent2h# 行数
                peakspexcurrent=sorted(peakspexcurrent)
                peaksperm=[]# 波峰行数
                peakspern=[]# 波谷行数
                permt=[]# 波峰时间
                pernt=[]# 波谷时间
                # 突减的最高转速开始，向左探索至3630的边界。
                permtlh=[]# 行数
                permtl=[]# 时间
                # 从突减的最高转速开始，向右探索至3630的边界。从permtr到pexcurrent1是突减保持时间段。
                permtrh=[]# 行数
                permtr=[]# 时间
                # 从突加的最低转速开始，向左探索至3570的边界。
                perntlh=[]# 行数
                perntl=[]# 时间
                # 从突加的最低转速开始，向右探索至3570的边界。从perntr到pexcurrent2是突加保持时间段。
                perntrh=[]# 行数
                perntr=[]# 时间
                for i in range(len(peakspexcurrent)-1):
                    if pexcurrent.iloc[peakspexcurrent[i]]>pexcurrent.iloc[peakspexcurrent[i+1]]:
                        peaksdf=per.iloc[peakspexcurrent[i]+1:peakspexcurrent[i+1]+1]
                        j=findextremum1(peaksdf,1)# 波峰时间
                        k=index_listm.index(j)# 波峰行数
                        permt.append(j)# 波峰时间
                        peaksperm.append(k)# 波峰行数
                        m=list3(j,pexcurrent1)
                        if per.loc[j]<3630:
                            permt.pop(-1)# 波峰时间
                            peaksperm.pop(-1)# 波峰行数
                            pexcurrent1h.pop(m)# 电流行数
                            pexcurrent1.pop(m)# 电流索引
                        else:
                            while int(per.iloc[k])>=int(3630):
                                if k==peakspexcurrent[i]+1:
                                    break
                                k -=1
                            permtlh.append(k)# 突减前小于3630的行数。
                            permtl.append(index_listm[k])# 突减前小于3630的时间。
                            k=index_listm.index(j)
                            while int(per.iloc[k])>=int(3630):
                                if k==peakspexcurrent[i+1]:
                                    k +=1
                                    break
                                k +=1
                            permtrh.append(k)# 突减后小于3630的行数。
                            permtr.append(index_listm[k])# 突减后小于3630的时间。
                            if k==peakspexcurrent[i+1]+1:
                                # 要修改
                                permtrh[-1]='    '# 突减后小于3630的行数。
                                permtr[-1]='    '# 突减后小于3630的时间。
                    elif pexcurrent.iloc[peakspexcurrent[i]]<pexcurrent.iloc[peakspexcurrent[i+1]]:
                        peaksdf=per.iloc[peakspexcurrent[i]+1:peakspexcurrent[i+1]+1]
                        j=findextremum1(peaksdf,2)# 波谷时间
                        k=index_listm.index(j)# 波谷行数
                        pernt.append(j)# 波谷时间
                        peakspern.append(k)# 波谷行数
                        m=list3(j,pexcurrent2)
                        if per.loc[j]>3570:
                            pernt.pop(-1)# 波峰时间
                            peakspern.pop(-1)# 波峰行数
                            pexcurrent2h.pop(m)# 电流行数
                            pexcurrent2.pop(m)# 电流索引
                        else:
                            while int(per.iloc[k])<=int(3570):
                                if k==peakspexcurrent[i]+1:
                                    break
                                k -=1
                            perntlh.append(k)# 突加前大于3570的行数。
                            perntl.append(index_listm[k])# 突加前大于3570的时间。
                            k=index_listm.index(j)
                            while int(per.iloc[k])<=int(3570):
                                if k==peakspexcurrent[i+1]:
                                    k +=1
                                    break
                                k +=1
                            perntrh.append(k)# 突加后大于3570的行数。
                            perntr.append(index_listm[k])# 突加后大于3570的时间。
                            if k==peakspexcurrent[i+1]+1:
                                # 要修改
                                perntrh[-1]='    '# 突加后大于3570的行数。
                                perntr[-1]='    '# 突加后大于3570的时间。
                tm=[]# 时间
                for i,j in zip(permtl,permtr):
                    if j=='    ':
                        tm.append('    ')# 突减恢复时间。
                    else:
                        tm.append(j-i)# 突减恢复时间。
                tn=[]# 时间
                for i,j in zip(perntl,perntr):
                    if j=='    ':
                        tn.append('    ')# 突加恢复时间。
                    else:
                        tn.append(j-i)# 突加恢复时间。
                permz=per.loc[permt]# 峰值。
                pernz=per.loc[pernt]# 谷值。
                plt.subplot(311)
                plt.plot(pernz, 'd')# 波谷的图像。
                plt.plot(permz, 'D')# 波峰的图像。
                # 突加点的缸温和进气温度
                pexcurrent1t=[]# 时间
                pettj=[]# 缸温
                piattj=[]# 进气温度
                for i,j in zip(pexcurrent1h,peakspern):
                    # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                    pexcurrent1t.append(index_listm[i+1])# 突加点的时间
                    pettj.append(pet.iloc[i+1])# 突加点的缸温。
                    piattj.append(piat.iloc[i+1])# 突加点的进气温度。
                # 缸温图
                plt.subplot(323)
                plt.title("缸温图像")
                plt.xlabel("时间/s")
                plt.ylabel("缸温/℃")
                plt.plot(pet)
                plt.plot(pexcurrent1t, pettj, 'h')
                # 进气温度图
                plt.subplot(325)
                plt.title("进气温度图像")
                plt.xlabel("时间/s")
                plt.ylabel("进气温度/℃")
                plt.plot(piat)
                plt.plot(pexcurrent1t, piattj, 'h')
                # 配合转速修正电流
                if len(permz)!=len(pexcurrent1):
                    pexcurrent1h.pop(0)# 去掉开头，人为修正数据# 行数
                    pexcurrent1.pop(0)# 去掉开头，人为修正数据# 索引
                elif len(pernz)!=len(pexcurrent2):
                    pexcurrent2h.pop(0)# 去掉开头，人为修正数据# 行数
                    pexcurrent2.pop(0)# 去掉开头，人为修正数据# 索引
                # 节气门体开度图
                plt.subplot(326)
                plt.title("节气门体开度图像")
                plt.xlabel("时间/s")
                plt.ylabel("节气门开度/°")
                plt.plot(ptd)
                ptd1=[]
                k=0
                for i,j in zip(perntr,pexcurrent2):# 突加转速恢复时间的右边界到电流从高处下降的时间是突加并保持的时间。
                    k+=1
                    print(k)
                    if i=='    ':
                        ptd1.append('    ')
                    else:
                        plt.subplot(324)
                        pexcurrent0=pexcurrent.loc[i:j]# 突加转速恢复时间的右边界到电流从高处下降的时间是突加保持时间段。
                        # 找到电流的变化点，处理变化的数据
                        pexcurrent0,pexcurrent0l1,pexcurrent0l2=Ruptures2(pexcurrent0)
                        plt.plot(pexcurrent0l1,pexcurrent0.loc[pexcurrent0l1],'s')# 异常值的图像。
                        plt.plot(pexcurrent0l2,pexcurrent0.loc[pexcurrent0l2],'s')# 异常值的图像。
                        # 处理变化点临近值
                        pexcurrent0,ptd0l1,ptd0l2=OutlierDetection1(pexcurrent0,pexcurrent0l1,pexcurrent0l2)
                        # plt.plot(pexcurrent0,'+', zorder=2)
                        plt.subplot(326)
                        # 反映到节气门开度上
                        ptd0=ptd.loc[pexcurrent0.index]
                        ptd0l2.insert(0, ptd0.index[0])
                        plt.plot(ptd0l1,ptd0.loc[ptd0l1],'s')# 异常值的图像。
                        plt.plot(ptd0l2,ptd0.loc[ptd0l2],'s')# 异常值的图像。
                        # 处理节气门开度稳定之前的变化点
                        ptd0l1=[]
                        ptd0l2=[ptd0.index[0]]
                        ptd0,ptd0l1,ptd0l2=OutlierDetection1(ptd0,ptd0l1,ptd0l2)# 节气门开度去除异常值
                        # 转速 >= 3570 or <= 3630 的变化点
                        ptd0,ptd0l1,ptd0l2=OutlierDetection3(ptd0,per)# 节气门开度突加后恢复时间
                        plt.plot(ptd0l1,ptd0.loc[ptd0l1],'o')# 异常值的图像。
                        plt.plot(ptd0l2,ptd0.loc[ptd0l2],'o')# 异常值的图像。
                        ptd0,ptd0l1,ptd0l2=OutlierDetection1(ptd0,ptd0l1,ptd0l2)# 节气门开度去除异常值
                        # 保留的数据至少要有2个
                        if len(ptd0)<=1:
                            ptd1.append('    ')
                        else:
                            pexcurrent0=pexcurrent0.loc[ptd0.index]
                            plt.subplot(324)
                            plt.plot(pexcurrent0,'+', zorder=2)
                            plt.subplot(326)
                            plt.plot(ptd0,'+')
                            ptd1.append(str(np.around(ptd0.min(), decimals=1))+'~'+str(np.around(ptd0.max(), decimals=1)))# 突加保持时间段的开度范围
                ptd2=[]
                for i,j in zip(permtr,pexcurrent1):# 突减转速恢复时间的右边界到电流将要上升的时间是突减并保持的时间。
                    if i=='    ':
                        ptd2.append('    ')
                    else:
                        plt.subplot(324)
                        pexcurrent0=pexcurrent.loc[i:j]# 节气门开度回升的时间到0A电流将要上升的时间是突减保持时间段。
                        # 电流的变化点
                        pexcurrent0,pexcurrent0l1,pexcurrent0l2=OutlierDetection2(pexcurrent0)
                        # plt.plot(pexcurrent0,'+', zorder=2)
                        plt.subplot(326)
                        # 反映到节气门开度上
                        ptd0=ptd.loc[pexcurrent0.index]
                        ptd0l1,ptd0l2=pexcurrent0l1,pexcurrent0l2
                        ptd0l2.insert(0, ptd0.index[0])
                        plt.plot(ptd0l1,ptd0.loc[ptd0l1],'s')# 异常值的图像。
                        plt.plot(ptd0l2,ptd0.loc[ptd0l2],'s')# 异常值的图像。
                        # 处理节气门开度稳定之前的变化点
                        ptd0l1=[]
                        ptd0l2=[ptd0.index[0]]
                        ptd0,ptd0l1,ptd0l2=OutlierDetection1(ptd0,ptd0l1,ptd0l2)# 节气门开度去除异常值
                        # 转速 >= 3570 or <= 3630 的变化点
                        ptd0,ptd0l1,ptd0l2=OutlierDetection3(ptd0,per)# 节气门开度突减后恢复时间
                        plt.plot(ptd0l1,ptd0.loc[ptd0l1],'o')# 异常值的图像。
                        plt.plot(ptd0l2,ptd0.loc[ptd0l2],'o')# 异常值的图像。
                        ptd0,ptd0l1,ptd0l2=OutlierDetection1(ptd0,ptd0l1,ptd0l2)# 节气门开度去除异常值
                        # 保留的数据至少要有2个
                        if len(ptd0)<=1:
                            ptd2.append('    ')
                        else:
                            pexcurrent0=pexcurrent0.loc[ptd0.index]
                            plt.subplot(324)
                            plt.plot(pexcurrent0,'+', zorder=2)
                            plt.subplot(326)
                            plt.plot(ptd0,'+')
                            ptd2.append(str(np.around(ptd0.min(), decimals=1))+'~'+str(np.around(ptd0.max(), decimals=1)))# 突减保持时间段的开度范围 <class 'numpy.float64'>
                # 判断是先突加后突减的一次或者多次循环还是其它的突加突减组合
                if len(ptd1) == len(ptd2) and pexcurrent2[0] < pexcurrent1[0]:
                    # 突加的最低转速降,突减的最高转速升,突加恢复时间,突减恢复时间,突加点的缸温,突加点的进气温度,突加保持时间段的开度范围,突减保持时间段的开度范围
                    l1='{0} 文件从 {1} s 到 {2} s 的突加突减数据分析完成，输出突加的最低转速降（rpm），突减的最高转速升（rpm），突加的转速恢复时间（s），突减的转速恢复时间（s），突加点的缸温（℃），突加点的进气温度（℃），突加保持时间段的开度范围（°），突减保持时间段的开度范围（°）：'.format(path,s,f)
                    l.append(l1)
                    for i in range(len(pernz)):
                        # print('第',i+1,'次','先突加后突减的循环中，突加的最低转速降是',pernz.values[i],'突减的最高转速升是',permz.values[i],'突加恢复时间是',tn[i],'突减恢复时间是',tm[i],'突加点的缸温是',pettj[i],'突加点的进气温度是',piattj[i],'突加保持时间段的开度范围是',ptd1[i],'突减保持时间段的开度范围',ptd2[i])
                        l2='第{0}次先突加后突减的循环中，突加的最低转速降（rpm）是{1}，突减的最高转速升（rpm）是{2}，突加的转速恢复时间（s）是{3}，突减的转速恢复时间（s）是{4}，突加点的缸温（℃）是{5}，突加点的进气温度（℃）是{6}，突加保持时间段的开度范围（°）是{7}，突减保持时间段的开度范围（°）是{8}。'.format(i+1,pernz.values[i].round(),permz.values[i].round(),tn[i],tm[i],pettj[i].round(2),piattj[i].round(2),ptd1[i],ptd2[i])
                        l.append(l2)
                else:
                    # 突加的最低转速降,突加恢复时间,突加点的缸温,突加点的进气温度,突加保持时间段的开度范围。
                    if len(ptd1) !=0:
                        l1='{0} 文件从 {1} s 到 {2} s 的突加突减数据分析完成，输出突加的最低转速降（rpm），突加的转速恢复时间（s），突加点的缸温（℃），突加点的进气温度（℃），突加保持时间段的开度范围（°）：'.format(path,s,f)
                        l.append(l1)
                    for i in range(len(ptd1)):
                        l2='第{0}次突加的最低转速降（rpm）是{1}，突加的转速恢复时间（s）是{2}，突加点的缸温（℃）是{3}，突加点的进气温度（℃）是{4}，突加保持时间段的开度范围（°）是{5}。'.format(i+1,pernz.values[i].round(),tn[i],pettj[i].round(2),piattj[i].round(2),ptd1[i])
                        l.append(l2)
                    n=len(l)
                    # 突减的最高转速升,突减恢复时间,突减保持时间段的开度范围。
                    if len(ptd2) !=0:
                        l1='{0} 文件从 {1} s 到 {2} s 的突加突减数据分析完成，输出突减的最高转速升（rpm），突减的转速恢复时间（s），突减保持时间段的开度范围（°）：'.format(path,s,f)
                        l.append(l1)
                    for i in range(len(ptd2)):
                        l2='第{0}次突减的最高转速升（rpm）是{1}，突减的转速恢复时间（s）是{2}，突减保持时间段的开度范围（°）是{3}。'.format(i+1,permz.values[i].round(),tm[i],ptd2[i])
                        l.append(l2)
            else:
                l0='打开 {0} 文件，输入要分析的突加突减数据的开始时间和结束时间。'.format(path)
                l.append(l0)
                plt.suptitle('{0}'.format(path))# 给画布添加标题
                # 显示转速和电流的原始图像，查找开始和结束点
                plt.subplot(211)
                plt.title("转速的原始图像")
                plt.plot(df['Per'])
                plt.xlabel("时间/s")
                plt.ylabel("转速/rpm")
                plt.subplot(212)
                plt.title("电流的原始图像")
                plt.plot(df['Pexcurrent'])
                plt.xlabel("时间/s")
                plt.ylabel("电流/A")
            # 自动调整子图的大小和位置，以确保它们之间以及与周围标签的间距是合适的。
            plt.tight_layout()
            plt.show()
        else:
            l0='{0} 文件没有转速的变量Per。'.format(path)
            l.append(l0)
    except Exception as e:
        print('\n','>>>' * 20)
        print(traceback.format_exc())
        l0='程序执行过程中发生异常。'
        l.append(l0)
        pass
    return l,n

# 提取给定时间范围内的首尾索引值
def sftime(df,s,f):
    sf=[]
    for i in range(len(df)):
        if s<=df.index[i]:
            sf.append(df.index[i])# 索引
            break
    for i in range(len(df)):
        if f<df.index[i]:
            sf.append(df.index[i-1])# 索引
            break
    return sf

# 列表去重
def list1(l):
    new_l=[]
    for i in l:
        if i not in new_l:
            new_l.append(i)
    return new_l

# 列表元素-1
def list2(l):
    for i,k in enumerate(l):# 对 i，k两个变量同时赋值，i 赋值为a当前元素的下标，k赋值为a当前的元素。
        l[i]=k-1
    return l

# 判断删除的电流的位置
def list3(x,l):
    for i,j in enumerate(l):
        if x<j:
            break
    return i

# 判断元素是否在系列里
def list4(df,l):
    ll=[]
    for i in l:
        if i in df.index:
            if i not in ll:
                ll.append(i)
    return ll

# 判断转速是否小于3570或者大于3630
def list5(df,l):
    ll=[]
    for i in l:
        if df.loc[i]>=3630 or df.loc[i]<=3570:
            ll.append(i)
    return ll

# 查找峰值和谷值（突加突减转速最大值和最小值）
def findextremum1(df,n):
    x=df.index
    y=df.values
    if n==1:
        # 找峰值
        dfMaxMin=np.max(y)
    else:
        # 找谷值
        dfMaxMin=np.min(y)
    Positon=np.where(y==dfMaxMin)# 返回行数
    Time=(x[Positon[0][0]])
    # 索引
    return Time

# 删除异常值前后的临近数据（大于或者小于平均值）
def OutlierDetection1(df,l1,l2):
    l=[]
    ll1=[]
    ll2=[]
    # 计算均值
    mean = df.mean()
    for i in l1:
        j=df.index.get_loc(i)
        # print('去除的异常数据的前一个数据的索引：',i)# 异常值的索引。
        # plt.plot(i,df.loc[i],'s')# 异常值的图像。
        if df.iloc[j]<mean:
            while df.iloc[j]<=mean:# 所有小于平均值的都去掉直到大于平均值,往前删除。
                if j==0:
                    l.append(df.index[j])
                    break
                l.append(df.index[j])
                j-=1
            ll1.append(df.index[j])
        elif df.iloc[j]>=mean:
            while df.iloc[j]>=mean:# 所有大于平均值的都去掉直到小于平均值,往前删除。
                if j==0:
                    l.append(df.index[j])
                    break
                l.append(df.index[j])
                j-=1
            ll1.append(df.index[j])
    for i in l2:
        j=df.index.get_loc(i)
        # print('去除的异常数据的后一个数据的索引：',i)# 异常值的索引。
        # plt.plot(i,df.loc[i],'s')# 异常值的图像。
        if df.iloc[j]<mean:
            while df.iloc[j]<=mean:# 所有小于平均值的都去掉直到大于平均值,往后删除。
                if j==len(df)-1:
                    l.append(df.index[j])
                    break
                l.append(df.index[j])
                j+=1
            ll2.append(df.index[j])
        elif df.iloc[j]>=mean:
            while df.iloc[j]>=mean:# 所有大于平均值的都去掉直到小于平均值,往后删除。
                if j==len(df)-1:
                    l.append(df.index[j])
                    break
                l.append(df.index[j])
                j+=1
            ll2.append(df.index[j])
    l=list1(l)
    data_cc=df.drop(l,axis=0)# 通过索引删除
    ll1=list4(data_cc,ll1)
    ll2=list4(data_cc,ll2)
    return data_cc,ll1,ll2

# 提取突减阶段电流为0A的数据
def OutlierDetection2(df):
    # 突减保持时间段电流为0A，所以不等于0A的数据是异常值
    l=[]
    ll=[]
    l1=[]
    l2=[]
    for i in range(len(df)):
        if df.iloc[i]!=0:
            l.append(df.index[i])# 异常值的时间索引
        else:
            ll.append(i)# 正常值的时间行数
    for i in ll:
        if i!=len(df)-1:
            if i+1 not in ll:
                l1.append(df.index[i])
        if i!=0:
            if i-1 not in ll:
                l2.append(df.index[i])
    # # 异常值
    # error=df.loc[l]
    # 正常值
    data_c=df.drop(l,axis=0)
    return data_c,l1,l2

# 转速突变影响节气门开度
def OutlierDetection3(df1,df2):
    df2=df2.loc[df1.index]
    l=[]
    ll=[]
    l1=[]
    l2=[]
    for i in range(len(df2)):
        if df2.iloc[i]>3570 and df2.iloc[i]<3630:
            ll.append(i)# 正常值的时间行数
        else:
            l.append(df2.index[i])# 异常值的时间索引
    for i in ll:
        if i!=len(df2)-1:
            if i+1 not in ll:
                l1.append(df2.index[i])
        if i!=0:
            if i-1 not in ll:
                l2.append(df2.index[i])
    # # 异常值
    # error=df1.loc[l]
    # 正常值
    df1=df1.drop(l,axis=0)
    return df1,l1,l2

# 整体判断电流变化点
def Ruptures1(df):
    l1=[]
    l11=[]
    l2=[]
    l21=[]
    # 用rbf模型去检测
    algo = rpt.Binseg(model="l2").fit(df.values)
    # 变化终止点的位数
    result = algo.predict(pen=5)# 位数
    result = list2(result)# 行数
    for i in range(len(result)-1):
        # 分段，左闭右开
        j=result[i]-100
        if j<0:
            j=0
        s1=df.iloc[j:result[i]].sum()
        s2=df.iloc[result[i]:result[i]+100].sum()
        # print('\ns1\n',s1/100,'\ns2\n',s2/100)
        if s1<s2:
            l1.append(result[i])# =0
        elif s1>s2:
            l2.append(result[i])# >0
    # # 显示结果
    # for i1 in l1:
    #     plt.axvline(x=df.index[i1], color='r', linestyle='--')# 以上一段变化的终止点为分割点，故-1。
    # for i2 in l2:
    #     plt.axvline(x=df.index[i2], color='y', linestyle='--')# 以上一段变化的终止点为分割点，故-1。
    j=0
    for i in l1:
        if df.iloc[i]==0:
            while df.iloc[i]==0:
                if i==len(df)-1:
                    l11.append(i)
                    j=1
                    break
                i+=1
            if j==0:
                l11.append(i-1)
        elif df.iloc[i]>0:
            while df.iloc[i]>0:
                if i==0:
                    l11.append(i)
                    j=1
                    break
                i-=1
            if j==0:
                l11.append(i)
        j=0
    for i in l2:
        if df.iloc[i]==0:
            while df.iloc[i]==0:
                if i==0:
                    l21.append(i)
                    j=1
                    break
                i-=1
            if j==0:
                l21.append(i)
        elif df.iloc[i]>0:
            while df.iloc[i]>0:
                if i==len(df)-1:
                    l21.append(i)
                    j=1
                    break
                i+=1
            if j==0:
                l21.append(i-1)
        j=0
    return l11,l21

# 使用ruptures来检测变量关系
# 通过变化点分割每个突加保持时间段的电流
# 删除突加阶段的异常值
def Ruptures2(df):
    l=[]
    l1=[]
    l2=[]
    dic={}
    dic1={}
    # 计算均值
    mean = df.mean()
    # 计算标准差
    std = df.std()
    # # 输出均值和标准差
    # print('均值为：{}（{}），标准差为：{}，均值加3倍标准差为：{}，均值减3倍标准差为：{}' .format(mean, mean*240, std, mean+3*std, mean-3*std))
    # 用rbf模型去检测
    algo = rpt.Pelt(model="l2").fit(df.values)
    # 变化终止点的位数
    result = algo.predict(pen=10)# 位数
    result = list2(result)# 行数
    # print('algo:','\n',algo,'\n',type(algo),'\n','result:','\n',result,'\n',type(result),'\n','df:','\n',df,'\n',type(df),'\n','df.values:','\n',df.values,'\n',type(df.values))
    # 分割线行数加上开头
    result.insert(0, 0)
    # 显示结果
    for bkp in result:
        plt.axvline(x=df.index[bkp], color='y', linestyle='--')# 以上一段变化的终止点为分割点，故-1。
    print('变化点的行数（包含起始位置）：',result)
    dfis = [ pd.Series() for _ in range(len(result)-1) ]
    for i in range(len(result)-1):
        if i==len(result)-2:
            dfis[i]=df.iloc[result[i]:result[i+1]+1]
        else:
            # 分段，左闭右开
            dfis[i]=df.iloc[result[i]:result[i+1]]
        meani=dfis[i].mean()
        # print('各段数据平均值：{}（{}）' .format(meani,meani*240))
        # print('各段数据最大最小值：{}-{}' .format(dfis[i].max(),dfis[i].min()))
        dic[i]=abs(mean-meani)
        dic1[i]='各段数据平均值：{}（{}）' .format(meani,meani*240)
        # dic1[i]=meani-mean
        # if not math.isclose(mean, meani, abs_tol = 0.4):# 如果两个值值接近，则返回 True
        #     l.append(result[i+1])
        if not math.isclose(mean, meani, abs_tol = 0.45):# 如果两个值值接近，则返回 True
            l.append(result[i+1])
    # print('各段数据平均值偏离总数据平均值的距离dic：\n',dic)
    if l:
        # 输出均值和标准差
        print('均值为：{}（{}），标准差为：{}，均值加3倍标准差为：{}，均值减3倍标准差为：{}' .format(mean, mean*240, std, mean+3*std, mean-3*std))
        print(dic1)
        # 显示结果
        for bkp in result:
            plt.axvline(x=df.index[bkp], color='r', linestyle='--')# 以上一段变化的终止点为分割点，故-1。
        while True:
            for key,value in dic.items():
                if(value == max(dic.values())):
                    if key==0:
                        l2.append(dfis[key+1].index[0])
                    elif key==len(dic)-1:
                        l1.append(dfis[key-1].index[-1])
                    else:
                        l1.append(dfis[key-1].index[-1])
                        l2.append(dfis[key+1].index[0])
                    df=df.drop(dfis[key].index)
                    dfis.pop(key)
            dic.pop(len(dfis))
            mean=df.mean()
            # print('总数据平均值：{}（{}）' .format(mean,mean*240))
            for i in range(len(dfis)):
                meani=dfis[i].mean()
                # print('各段数据平均值：{}（{}）' .format(meani,meani*240))
                dic[i]=abs(mean-meani)
            # print('删除最大偏离数据后，各段数据平均值偏离总数据平均值的距离dic：\n',dic)
            if all(math.isclose(dic[i], dic[i+1], abs_tol = 0.25) for i in range(len(dic)-1)):# 判断都满足条件
                break
        l1=list4(df,l1)
        l2=list4(df,l2)
    return df,l1,l2

# # 查找峰值和谷值
# def OutlierDetection4(df):
#     # 找峰值
#     peaksdf, _ = scipy.signal.find_peaks(df,distance=len(df))# 符合条件的行号，height代表峰顶点的高度范围，distance代表峰与峰的最小距离。
#     dft=[]
#     for i in peaksdf:
#         dft.append(df.index[i])# 列表的下标即为当前行号，输入行号，即可获得当前行对应的索引号
#     dfz=df.loc[dft]# 极值
#     plt.plot(dft, dfz,'s')# 极值的图像。
#     # CurveSmoothing(dfz)
#     # print('dfz的长度：',len(dfz))
#     return dft,dfz

# # 删除靠近不稳定阶段的数据
# def OutlierDetection2(df):
#     l=[]
#     # 计算均值
#     mean = df.mean()
#     i=0
#     if df.iloc[i]<mean:
#         while df.iloc[i]<=mean:
#             if i==len(df)-1:
#                 l.append(df.index[i])
#                 break
#             l.append(df.index[i])
#             i+=1
#     elif df.iloc[i]>=mean:
#         while df.iloc[i]>=mean:
#             if i==len(df)-1:
#                 l.append(df.index[i])
#                 break
#             l.append(df.index[i])
#             i+=1
#     data_cc=df.drop(l,axis=0)# 通过索引删除
#     return data_cc

# # 突加突减没有稳定时，电流突变干扰
# def OutlierDetection4(df1,df2):
#     df2=df2.loc[df1.index]
#     i=0
#     l=[]
#     if df2.iloc[i]<=3570:
#         while df2.iloc[i]<=3570:
#             if i==len(df2)-1:
#                 l.append(df2.index[i])
#                 break
#             l.append(df2.index[i])
#             i+=1
#     elif df2.iloc[i]>=3630:
#         while df2.iloc[i]>=3630:
#             if i==len(df2)-1:
#                 l.append(df2.index[i])
#                 break
#             l.append(df2.index[i])
#             i+=1
#     df1=df1.drop(l,axis=0)
#     if len(l)>0 and len(df1)>0:
#         df1=OutlierDetection2(df1)
#     return df1

# # 突加没有稳定时，电流突变干扰
# def OutlierDetection4(df1,df2):
#     df2=df2.loc[df1.index]
#     k=[]
#     l1=[]# 左索引
#     l2=[]# 右索引
#     l=[]# 行数
#     i=findextremum1(df2,1)# 索引
#     j=df2.index.get_loc(i)# 行数
#     while int(df2.iloc[j])>=int(3630):
#         k.append(i)
#         while int(df2.iloc[j])>=int(3630):
#             if j==0:
#                 l.append(df2.index[j])
#                 break
#             l.append(df2.index[j])
#             j -=1
#         l1.append(df2.index[j])
#         j=df2.index.get_loc(i)# 行数
#         while int(df2.iloc[j])>=int(3630):
#             if j==len(df2)-1:
#                 l.append(df2.index[j])
#                 break
#             l.append(df2.index[j])
#             j +=1
#         l2.append(df2.index[j])
#         df2=df2.drop(l,axis=0)
#         if not df2.empty:
#             break
#         l=[]
#         i=findextremum1(df2,1)# 索引
#         j=df2.index.get_loc(i)# 行数
#     if df2.empty:
#         i=findextremum1(df2,2)# 索引
#         j=df2.index.get_loc(i)# 行数
#         while int(df2.iloc[j])<=int(3570):
#             k.append(i)
#             while int(df2.iloc[j])<=int(3570):
#                 if j==0:
#                     l.append(df2.index[j])
#                     break
#                 l.append(df2.index[j])
#                 j -=1
#             l1.append(df2.index[j])
#             j=df2.index.get_loc(i)# 行数
#             while int(df2.iloc[j])<=int(3570):
#                 if j==len(df2)-1:
#                     l.append(df2.index[j])
#                     break
#                 l.append(df2.index[j])
#                 j +=1
#             l2.append(df2.index[j])
#             df2=df2.drop(l,axis=0)
#             if not df2.empty:
#                 break
#             l=[]
#             i=findextremum1(df2,2)# 索引
#             j=df2.index.get_loc(i)# 行数
#     df1=df1.loc[df2.index]
#     l1=list4(df1,l1)
#     l2=list4(df1,l2)
#     return k,df1,l1,l2

# # 突减没有稳定时，电流突变干扰
# def OutlierDetection5(df,l1,l2):
#     for i in l1:
#         j=df.index.get_loc(i)
#         print('去除的异常数据的前一个数据的索引：',df.index[j])# 异常值的索引。
#         plt.plot(df.index[j],df.iloc[j],'s')# 异常值的图像。
#     for i in l2:
#         j=df.index.get_loc(i)
#         print('去除的异常数据的后一个数据的索引：',df.index[j])# 异常值的索引。
#         plt.plot(df.index[j],df.iloc[j],'s')# 异常值的图像。

# # 突加没有稳定时，电流突变干扰
# def OutlierDetection4(df1,df2):
#     i=df1.index[0]# 索引
#     j=df2.index.get_loc(i)# 行数
#     if df2.iloc[j]<3570:
#         while df2.iloc[j]<3570:
#             if j==len(df2)-1:
#                 break
#             j+=1
#     df1=df1.loc[df2.index[j]:]
#     df1=OutlierDetection2(df1)
#     return df1

# # 异常值检测（3σ法则）
# def OutlierDetection4(df):
#     l1=[]
#     l2=[]
#     error = pd.DataFrame()
#     # 计算均值
#     mean = df.mean()
#     # 计算标准差
#     std = df.std()
#     # 输出均值和标准差
#     print('均值为：{}，标准差为：{}，均值加3倍标准差为：{}，均值减3倍标准差为：{}' .format(mean, std, mean+3*std, mean-3*std))
#     # 定义3σ法则识别异常值
#     # 识别异常值
#     error = df[np.abs(df - mean) > 3 * std]
#     # 剔除异常值，保留正常的数据
#     data_c = df[np.abs(df - mean) <= 3 * std]
#     for i in data_c.index:
#         j=df.index.get_loc(i)# 行数
#         if j!=len(df)-1:
#             if df.index[j+1] not in data_c.index:
#                 l1.append(i)
#         if i!=0:
#             if df.index[j-1] not in data_c.index:
#                 l2.append(i)
#     return error,data_c,l1,l2

# # ADF检测
# def ADFStatistics(df):
#     # cl=[]
#     values=df.values
#     res = adfuller(values)
#     # 打印 adfuller 测试的统计结果
#     print('ADF统计：%f' % res[0])
#     print('p值：%f' % res[1])
#     # 打印不同 alpha 级别的临界值。
#     print('不同层次的临界值：')
#     l=[]
#     for k, v in res[4].items():
#         l.append(v)
#         print('\t%s: %.3f' % (k, v))
#     result = all(res[0] >v  for v in l)
#     if res[1]>0.05 and result==True:
#         print('时间序列数据是强非平稳的')

# # 简单线性回归
# def Simplelinearregression(df,result):
#     # # 显示数据的拟合线
#     # print('变化点的行数（包含起始位置）：',result)
#     # 提取xy
#     x=df.index
#     y=df.values
#     # 计算回归系数
#     slope, intercept = np.polyfit(x, y, 1)
#     # 绘制拟合曲线    # plt.scatter(x, y)# 绘制散点图
#     coeff1 = slope * x + intercept
#     plt.plot(x, coeff1, color='b',ls = '-', marker='*')
#     # 显示分段拟合线
#     for i in range(len(result)-1):
#         # 分段，左闭右开
#         dfi=df.loc[df.index[result[i]]:df.index[result[i+1]]]
#         # 提取xy
#         x=dfi.index
#         y=dfi.values
#         # 计算回归系数
#         slope, intercept = np.polyfit(x, y, 1)
#         # 绘制拟合曲线        # plt.scatter(x, y)# 绘制散点图
#         coeff2 = slope * x + intercept
#         if i==0:
#             coeff3=coeff2
#         else:
#             coeff3=np.append(coeff3,coeff2[1:])
#         plt.plot(x, coeff2, color='r',ls = '-', marker='o')

# # 异常值检测（3σ法则）数组检测
# def OutlierDetection4(a):
#     # 3σ法则去掉突加保持时间段的异常值
#     # 计算均值
#     mean = a.mean()
#     # 计算标准差
#     std = a.std()
#     # 输出均值和标准差
#     print('均值为：%.3f，标准差为：%.3f，均值加3倍标准差为：%.3f，均值减3倍标准差为：%.3f' % (mean, std, mean+3*std, mean-3*std))
#     # 定义3σ法则识别异常值
#     # 识别异常值
#     error = a[np.abs(a - mean) > 3 * std]
#     # 剔除异常值，保留正常的数据
#     data_c = a[np.abs(a - mean) <= 3 * std]
#     return error,data_c

# # 曲线平滑
# def CurveSmoothing(df):
#     y = scipy.signal.savgol_filter(df.values, len(df)*2//100+1, 0)
#     plt.plot(df.index,y,'-')

# # 查找数据的离散程度相差很大的点
# def val_eb(x,y,gap):
# # 转折点前后数据的离散程度相差很大，用这个离散差异拟合一条曲线，可能会有奇效。
# # 对每一个数据点（离散数据点拟合的曲线），向前向后分别取一段等长区间，分别求方差，用方差表示离散程度。用向前区间的方差/向后区间的方差，表示离散差异。
# # 每个数据点求得的离散差异形成的曲线如下，极值点x=790，正是转折点。
#     col=[]
#     y_col = []
#     for i in range(gap, len(y) - gap):
#         col.append(np.var(y[i - gap:i]) / np.var(y[i:i + gap]))
#         y_col.append(i)
#     return col,y_col

# # 通过变化点分割每个突加保持时间段的电流
# def Ruptures1(df):
#     l=[]
#     dic={}
#     dic1={}
#     dic2={}
#     # 计算均值
#     mean = df.mean()
#     # 计算标准差
#     std = df.std()
#     # 输出均值和标准差
#     print('均值为：{}，标准差为：{}，均值加3倍标准差为：{}，均值减3倍标准差为：{}' .format(mean, std, mean+3*std, mean-3*std))
#     # 用rbf模型去检测
#     algo = rpt.Pelt(model="l2").fit(df.values)
#     # 变化终止点的位数
#     result = algo.predict(pen=5)# 位数
#     result = list2(result)# 行数
#     # 分割线行数加上开头
#     result.insert(0, 0)
#     # 显示结果
#     for bkp in result:
#         plt.axvline(x=df.index[bkp], color='y', linestyle='--')# 以上一段变化的终止点为分割点，故-1。
#     print('变化点的行数（包含起始位置）：',result)
#     dfis = [ pd.Series() for _ in range(len(result)-1) ]
#     for i in range(len(result)-1):
#         if i==len(result)-2:
#             dfis[i]=df.iloc[result[i]:result[i+1]+1]
#         else:
#             # 分段，左闭右开
#             dfis[i]=df.iloc[result[i]:result[i+1]]
#         meani=dfis[i].mean()
#         print('各段数据平均值：',meani)
#         dic[i]=abs(mean-meani)
#         dic1[i]=meani-mean
#         if not math.isclose(mean, meani, abs_tol = 0.4):# 如果两个值值接近，则返回 True
#             l.append(result[i+1])
#     # print('各段数据平均值到总数据平均值的距离dic:\n',dic)
#     for i in range(len(dic1)-1):
#         dic2[i]=abs(dic1[i]-dic1[i+1])
#     print('各段数据与下一段数据的平均值距离dic2：\n',dic2)
#     if l:
#         # 显示结果
#         for bkp in result:
#             plt.axvline(x=df.index[bkp], color='r', linestyle='--')# 以上一段变化的终止点为分割点，故-1。
#         while True:
#             for key,value in dic.items():
#                 if(value == max(dic.values())):
#                     df=df.drop(dfis[key].index)
#                     dfis.pop(key)
#             dic.pop(len(dfis))
#             dic1.pop(len(dfis))
#             dic2.pop(len(dic1)-1)
#             mean=df.mean()
#             print('总数据平均值：',mean)
#             for i in range(len(dfis)):
#                 meani=dfis[i].mean()
#                 print('各段数据平均值：',meani)
#                 dic[i]=abs(mean-meani)
#                 dic1[i]=meani-mean
#             # print('删除最大偏离数据后，各段数据的偏离值dic:\n',dic)
#             for i in range(len(dic1)-1):
#                 dic2[i]=abs(dic1[i]-dic1[i+1])
#             print('删除最大偏离数据后，各段数据与下一段数据的平均值距离dic2：\n',dic2)
#             if all(value <= 1 for key,value in dic2.items()):# 判断都满足条件
#                 break
#     return df

# # 通过变化点分割总电流-大罚值
# def Ruptures2(df):
#     l1=[]
#     l11=[]
#     l2=[]
#     l21=[]
#     # 用rbf模型去检测
#     algo = rpt.Binseg(model="l2").fit(df.values)
#     # 变化终止点的位数
#     result = algo.predict(pen=10000)# 位数
#     result = list2(result)# 行数
#     for i in range(len(result)-1):
#         # 分段，左闭右开
#         s1=df.iloc[result[i]-100:result[i]].sum()
#         s2=df.iloc[result[i]:result[i]+100].sum()
#         # print('\ns1\n',s1/100,'\ns2\n',s2/100)
#         if s1<s2:
#             l1.append(result[i])# =0
#         elif s1>s2:
#             l2.append(result[i])# >0
#     for i in l1:
#         if df.iloc[i]==0:
#             while df.iloc[i]==0:
#                 i+=1
#             l11.append(i-1)
#         elif df.iloc[i]>0:
#             while df.iloc[i]>0:
#                 i-=1
#             l11.append(i)
#     for i in l2:
#         if df.iloc[i]==0:
#             while df.iloc[i]==0:
#                 i-=1
#             l21.append(i)
#         elif df.iloc[i]>0:
#             while df.iloc[i]>0:
#                 i+=1
#             l21.append(i-1)
#     return l11,l21

# # 查找拐点（变化大的点）
# def OutlierDetection3(df):
#     # mean = df.mean()
#     # plt.axhline(mean)
#     dft1,dfz1=findextremum2(df,1)# 查找峰值
#     dfd=OutlierDetection1(abs(dfz1.diff()).iloc[1:],1)[0]# 异常值检测（3σ法则）# 与前一项高度差距过大
#     plt.plot(dfz1.loc[dfd.index], 'd')# 异常值
#     dft2,dfz2=findextremum2(df,2)# 查找谷值    # dfz2.diff().iloc[1:].to_csv('dfd.txt', mode='a')    # with open('dfd.txt', "a") as f:    #     f.write('一阶段结束\n')
#     dfd=OutlierDetection1(abs(dfz2.diff()).iloc[1:],1)[0]
#     plt.plot(dfz2.loc[dfd.index], 'd')# 异常值
#     # plt.plot([dft2[0],dft2[-1]],[(dfz2.values[0]+dfz1.values[0])/2,(dfz2.values[-1]+dfz1.values[-1])/2],'o-')# 首尾中线

# # （——\__/——）→查找峰值和谷值
# def findextremum2(df,n):
#     if n==1:
#         # 找峰值
#         peaksdf, _ = scipy.signal.find_peaks(df,distance=5)# 符合条件的行号，height代表峰顶点的高度范围，distance代表峰与峰的最小距离。
#     else:
#         # 找谷值
#         peaksdf, _ = scipy.signal.find_peaks(df*-1,distance=5)# 符合条件的行号，height代表峰顶点的高度范围，distance代表峰与峰的最小距离。
#     dft=[]
#     for i in peaksdf:
#         dft.append(df.index[i])# 列表的下标即为当前行号，输入行号，即可获得当前行对应的索引号
#     dfz=df.loc[dft]# 极值
#     plt.plot(dft, dfz)# 极值的图像。
#     # CurveSmoothing(dfz)
#     # print('dfz的长度：',len(dfz))
#     return dft,dfz


# # （——\__/——）→查找峰值和谷值
# def findextremum3(df,n):
#     if n==1:
#         # 找峰值
#         peaksdf, _ = scipy.signal.find_peaks(df, height=[3630,4000])# 符合条件的行号，height代表峰顶点的高度范围，distance代表峰与峰的最小距离。
#     else:
#         # 找谷值
#         peaksdf, _ = scipy.signal.find_peaks(df*-1, height=[-3570,-3000])# 符合条件的行号，height代表峰顶点的高度范围，distance代表峰与峰的最小距离。
#     dft=[]
#     for i in peaksdf:
#         dft.append(df.index[i])# 列表的下标即为当前行号，输入行号，即可获得当前行对应的索引号
#     dfz=df.loc[dft]# 极值
#     plt.plot(dft, dfz)# 极值的图像。
#     # CurveSmoothing(dfz)
#     # print('dfz的长度：',len(dfz))
#     return dft,dfz

# # 异常值检测（3σ法则）电流检测
# def OutlierDetection1(df,n):
#     if n==1:# 3σ法则去掉突加保持时间段的异常值
#         # 计算均值
#         mean = df.mean()
#         # 计算标准差
#         std = df.std()
#         # 输出均值和标准差
#         print('均值为：{}，标准差为：{}，均值加3倍标准差为：{}，均值减3倍标准差为：{}' .format(mean, std, mean+3*std, mean-3*std))
#         # 定义3σ法则识别异常值
#         # 识别异常值
#         error = df[np.abs(df - mean) > 3 * std]
#         # 剔除异常值，保留正常的数据
#         data_c = df[np.abs(df - mean) <= 3 * std]
#     else:# 突减保持时间段电流为0A，所以不等于0A的数据是异常值
#         l=[]
#         for i in range(len(df)):
#             if df.iloc[i]!=0:
#                 l.append(df.index[i])
#         error=df.loc[l]
#         data_c=df.drop(l,axis=0)
#     return error,data_c

# # 突加时节气门开度转折点
# def turningpoint(df):
#     # 计算均值
#     mean = df.mean()
#     # print('均值为：{}。' .format(mean))
#     i=0
#     if df.iloc[i]<mean:
#         while df.iloc[i]<mean:
#             if i==len(df)-1:
#                 break
#             i+=1
#     elif df.iloc[i]>=mean:
#         while df.iloc[i]>=mean:
#             if i==len(df)-1:
#                 break
#             i+=1
#     j=df.index[i]# 时间
#     return j# 索引

# # 转速转折点
# def turningpoint1(df):
#     # print('均值为：{}。' .format(mean))
#     i=0
#     if df.iloc[i]<3570:
#         while df.iloc[i]<3570:
#             if i==len(df)-1:
#                 break
#             i+=1
#     elif df.iloc[i]>=3630:
#         while df.iloc[i]>=3630:
#             if i==len(df)-1:
#                 break
#             i+=1
#     j=df.index[i]# 时间
#     return j# 索引
# # 异常值检测（大于或者小于平均值）
# def OutlierDetection1(df):
#     l=[]
#     # 计算均值
#     mean = df.mean()
#     for i in range(len(df)-1):
#         # 删除开头数据
#         j=i
#         if i==0:
#             if df.iloc[j]<mean:
#                 while df.iloc[j]<mean:
#                     if j==len(df)-1:
#                         l.append(df.index[j])
#                         break
#                     l.append(df.index[j])
#                     j+=1
#             elif df.iloc[j]>=mean:
#                 while df.iloc[j]>=mean:
#                     if j==len(df)-1:
#                         l.append(df.index[j])
#                         break
#                     l.append(df.index[j])
#                     j+=1
#         # 删除末尾数据
#         j=i
#         if i==len(df)-2:
#             j+=1
#             if df.iloc[j]<mean:
#                 while df.iloc[j]<mean:# 所有小于平均值的都去掉直到大于平均值,往前删除。
#                     if j==0:
#                         l.append(df.index[j])
#                         break
#                     l.append(df.index[j])
#                     j-=1
#             elif df.iloc[j]>=mean:
#                 while df.iloc[j]>=mean:# 所有大于平均值的都去掉直到小于平均值,往前删除。
#                     if j==0:
#                         l.append(df.index[j])
#                         break
#                     l.append(df.index[j])
#                     j-=1
#         # 删除中间缺少数据
#         j=i
#         if df.index[j+1]-df.index[j]>0.008:
#             print('异常值起点：',df.index[j])
#             print('异常值止点：',df.index[j+1])
#             plt.plot(df.index[j],df.iloc[j],'s')# 异常值起点的图像。
#             plt.plot(df.index[j+1],df.iloc[j+1],'s')# 异常值止点的图像。
#             o=j
#             s=j+1
#             if df.iloc[o]<mean:
#                 while df.iloc[o]<mean:# 所有小于平均值的都去掉直到大于平均值,往前删除。
#                     if o==0:
#                         l.append(df.index[o])
#                         break
#                     l.append(df.index[o])
#                     o-=1
#             elif df.iloc[o]>=mean:
#                 while df.iloc[o]>=mean:# 所有大于平均值的都去掉直到小于平均值,往前删除。
#                     if o==0:
#                         l.append(df.index[o])
#                         break
#                     l.append(df.index[o])
#                     o-=1
#             if df.iloc[s]<mean:
#                 while df.iloc[s]<mean:# 所有小于平均值的都去掉直到大于平均值,往后删除。
#                     if s==len(df)-1:
#                         l.append(df.index[s])
#                         break
#                     l.append(df.index[s])
#                     s+=1
#             elif df.iloc[s]>=mean:
#                 while df.iloc[s]>=mean:# 所有大于平均值的都去掉直到小于平均值,往后删除。
#                     if s==len(df)-1:
#                         l.append(df.index[s])
#                         break
#                     l.append(df.index[s])
#                     s+=1
#     l=list1(l)
#     data_cc=df.drop(l,axis=0)# 通过索引删除
#     return data_cc
